using System;
using System.Collections.Generic;
using System.Text;
using NBusiness.CodeDom;
using System.Reflection;
using NBusiness.Templates;
using NBusiness.Utilities;
using NBusiness.CodeDom.Compiler;
using NBusiness.ESharp.Compiler;

namespace NBusiness.CodeDom
{
    [Serializable]
    public class EntityTemplate
    {
        #region Members
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _type;
        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        private string _in;
        public string In
        {
            get { return _in; }
            set { _in = value; }
        }

        private List<Entity> _entities = new List<Entity>();
        public List<Entity> Entities
        {
            get { return _entities; }
        }

        private EntityRoot _parent;
        public EntityRoot Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        #endregion

        #region Constructors
        public EntityTemplate() { }
        public EntityTemplate(string name, string type, string @in)
        {
            _name = name;
            _type = type;
            _in = @in;
        }
        #endregion

        #region Generate
        public EntityResourceFile[] Generate(PartialLanguage partialLanguage)
        {
            EntityResourceFile[] files = new EntityResourceFile[] { };

            Type t = System.Type.GetType(Type + ", " + In);
            if (t == null)
                throw new ArgumentException(
                    "Invalid template: '" + Name + 
                    "' Type '" + _type + ", " + _in + 
                    "' not found");

            object obj = Activator.CreateInstance(t);

            if (!(obj is ITemplate))
                throw new ArgumentException("Invalid template: '" + Name + "' must implement from NBusiness.Templates.ITemplate");

            if (_entities.Count > 0)
            {
                ITemplate template = obj as ITemplate;
                template.Warning += new EventHandler<EntityBuildErrorEventArgs>(template_Warning);
                files = template.Generate(partialLanguage, _entities.ToArray());
            }
            return files;
        }

        void template_Warning(object sender, EntityBuildErrorEventArgs e)
        {
            OnBuildError(e.Error);
        }

        public EventHandler<EntityBuildErrorEventArgs> BuildError;
        protected virtual void OnBuildError(EntityBuildError error)
        {
            if (BuildError != null) BuildError(this, new EntityBuildErrorEventArgs(error));
        }
        #endregion

        #region object overrides
        public override string ToString()
        {
            return Name;
        }

        public override bool Equals(object obj)
        {
            bool equal = false;
            if (obj is EntityTemplate)
            {
                EntityTemplate t = obj as EntityTemplate;
                equal = (t.Name == this.Name && t.In == this.In);
            }
            return equal;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion        
    }
}
